package com.sunny.netty.handler;

import com.sunny.netty.entity.OrderRequest;
import com.sunny.netty.entity.OrderResponse;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

/**
 * 序列化服务端
 *
 * @author sunny
 * @date 2018/12/10
 */
public class OrderServer extends ChannelInitializer {

    @Override
    protected void initChannel(Channel channel) throws Exception {
        //解码器ObjectDecoder(int maxObjectSize, ClassResolver classResolver)第一个参数是设置序列化对象的最大字节长度，如果超出限定范围会抛出
        //StreamCorruptedException，默认（1024 * 1024 = 1048576字节），第二个参数用于做类解码操作
        channel.pipeline().addLast(new ObjectDecoder(1024 * 1024, ClassResolvers.weakCachingResolver(this.getClass().getClassLoader())))
                //编码器
                .addLast(new ObjectEncoder())
                .addLast(new OrderServerHandler());
    }

    private class OrderServerHandler extends ChannelHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            OrderRequest request = (OrderRequest) msg;
            if ("Sunny".equalsIgnoreCase(request.getUserName())) {
                System.out.println("Service Accept Client Order Request:[" + request.toString() + "]");
                ctx.writeAndFlush(response(request.getOrderId()));
            }
        }

        private OrderResponse response(Integer orderId) {
            OrderResponse orderResponse = new OrderResponse();
            orderResponse.setOrderId(orderId);
            orderResponse.setRespCode("200");
            orderResponse.setDesc("下单成功");
            return orderResponse;
        }
    }

    public static void bind(int port) {
        NioEventLoopGroup masterGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();

        bootstrap.group(masterGroup, workerGroup).channel(NioServerSocketChannel.class)
                //连接数
                .option(ChannelOption.SO_BACKLOG, 100)
                .childHandler(new OrderServer());

        try {
            //绑定端口，同步等待成功,
            System.out.println("绑定端口,同步等待成功......");
            ChannelFuture future = bootstrap.bind(port).sync();
            //等待服务端监听端口关闭
            future.channel().closeFuture().sync();
            System.out.println("等待服务端监听端口关闭......");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            masterGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        OrderServer.bind(4040);
    }
}
